package vip.aster.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import vip.aster.common.service.DictService;
import vip.aster.common.utils.PageInfo;
import vip.aster.system.entity.SysDictData;
import vip.aster.system.entity.SysDictType;
import vip.aster.system.mapper.SysDictDataMapper;
import vip.aster.system.mapper.SysDictTypeMapper;
import vip.aster.system.query.SysDictDataQuery;
import vip.aster.system.service.SysDictDataService;
import vip.aster.common.utils.DictUtils;
import vip.aster.system.vo.SysDictDataVO;

import java.util.List;

/**
 * <p>
 * 字典数据 服务实现类
 * </p>
 *
 * @author Aster
 * @since 2023-11-28 10:36
 */
@Service
@AllArgsConstructor
public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDictData>
        implements SysDictDataService, DictService {
    private SysDictDataMapper sysDictDataMapper;
    private SysDictTypeMapper sysDictTypeMapper;

    @Override
    public PageInfo<SysDictDataVO> pageList(SysDictDataQuery query) {
        Page<SysDictData> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<SysDictData> pageList = this.page(page, getWrapper(query));
        return new PageInfo<>(SysDictDataVO.convertList(pageList.getRecords()), pageList.getTotal());
    }

    @Override
    public void saveData(SysDictDataVO dictDataVO) {
        SysDictData dictData = new SysDictData();
        BeanUtil.copyProperties(dictDataVO, dictData, true);
        if (StrUtil.isNotBlank(dictData.getId())) {
            sysDictDataMapper.updateById(dictData);
        } else {
            sysDictDataMapper.insert(dictData);
        }
        // 更新缓存
        List<SysDictData> dataList = this.getDataByTypId(dictData.getDictTypeId());
        SysDictType dictType = sysDictTypeMapper.selectById(dictData.getDictTypeId());
        DictUtils.setDictCache(dictType.getDictType(), SysDictData.convertList(dataList));
    }

    @Override
    public List<SysDictData> getDataByTypId(String dictTypeId) {
        LambdaQueryWrapper<SysDictData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictData::getDictTypeId, dictTypeId);
        return this.list(queryWrapper);
    }

    @Override
    public void removeDictDataByIds(List<String> idList) {
        for (String id : idList) {
            SysDictData dictData = this.getById(id);
            this.removeById(id);
            List<SysDictData> dataList = this.getDataByTypId(dictData.getDictTypeId());
            SysDictType dictType = sysDictTypeMapper.selectById(dictData.getDictTypeId());
            DictUtils.setDictCache(dictType.getDictType(), SysDictData.convertList(dataList));
        }
    }

    @Override
    public String getDictLabel(String dictType, String dictValue) {
        if (StrUtil.isBlank(dictType) || StrUtil.isBlank(dictValue)) {
            return null;
        }
        // 先从缓存中拿
        String label = DictUtils.getDictLabel(dictType, dictValue);
        if (StrUtil.isBlank(label)) {
            // 缓存没有再从数据库拿
            LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StrUtil.isNotBlank(dictType), SysDictType::getDictType, dictType);
            SysDictType type = sysDictTypeMapper.selectOne(queryWrapper);
            if (type == null) {
                return null;
            }
            List<SysDictData> dictDataList = this.getDataByTypId(type.getId());
            if (CollUtil.isEmpty(dictDataList)) {
                return null;
            }
            List<String> labelList = dictDataList.stream().filter(
                    f -> f.getDictValue().equals(dictValue)).map(SysDictData::getDictLabel).toList();
            return CollUtil.isNotEmpty(labelList) ? labelList.get(0) : null;
        }
        return label;
    }

    @Override
    public String getDictLabel(String dictType, String dictValue, String separator) {
        if (StrUtil.isBlank(dictType) || StrUtil.isBlank(dictValue)) {
            return null;
        }
        if (StrUtil.containsAny(dictValue, separator)) {
            String label = DictUtils.getDictLabel(dictType, dictValue, separator);
            if (StrUtil.isBlank(label)) {
                List<String> values = StrUtil.split(dictValue, separator);
                StringBuilder propertyString = new StringBuilder();
                for (String value : values) {
                    String labelValue = this.getDictLabel(dictType, value);
                    propertyString.append(labelValue).append(separator);
                }
                label = StrUtil.stripIgnoreCase(propertyString.toString(), separator);
            }
            return label;
        } else {
            return this.getDictLabel(dictType, dictValue);
        }
    }

    @Override
    public String getDictValue(String dictType, String dictLabel) {
        if (StrUtil.isBlank(dictType) || StrUtil.isBlank(dictLabel)) {
            return null;
        }
        // 先从缓存中拿
        String value = DictUtils.getDictValue(dictType, dictLabel);
        if (StrUtil.isBlank(value)) {
            // 缓存没有再从数据库拿
            LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StrUtil.isNotBlank(dictType), SysDictType::getDictType, dictType);
            SysDictType type = sysDictTypeMapper.selectOne(queryWrapper);
            if (type == null) {
                return null;
            }
            List<SysDictData> dictDataList = this.getDataByTypId(type.getId());
            if (CollUtil.isEmpty(dictDataList)) {
                return null;
            }
            List<String> valueList =
                    dictDataList.stream().filter(
                            f -> f.getDictLabel().equals(dictLabel)).map(SysDictData::getDictValue).toList();
            value = CollUtil.isNotEmpty(valueList) ? valueList.get(0) : null;
        }
        return value;
    }

    @Override
    public String getDictValue(String dictType, String dictLabel, String separator) {
        if (StrUtil.isBlank(dictType) || StrUtil.isBlank(dictLabel)) {
            return null;
        }
        if (StrUtil.containsAny(dictLabel, separator)) {
            String value = DictUtils.getDictValue(dictType, dictLabel, separator);
            if (StrUtil.isBlank(value)) {
                List<String> labels = StrUtil.split(dictLabel, separator);
                StringBuilder propertyString = new StringBuilder();
                for (String label : labels) {
                    String valueValue = this.getDictValue(dictType, label);
                    propertyString.append(valueValue).append(separator);
                }
                value = StrUtil.stripIgnoreCase(propertyString.toString(), separator);
            }
            return value;
        } else {
            return this.getDictValue(dictType, dictLabel);
        }
    }

    private Wrapper<SysDictData> getWrapper(SysDictDataQuery query) {
        LambdaQueryWrapper<SysDictData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDictData::getDictTypeId, query.getDictTypeId());
        wrapper.orderByAsc(SysDictData::getSort);
        return wrapper;
    }
}
